package org.ojudge.ojudgecodesandbox.utils;

import lombok.extern.slf4j.Slf4j;
import org.ojudge.ojudgecodesandbox.modal.ExecuteMessage;
import org.springframework.util.StopWatch;

import java.io.*;
import java.nio.charset.StandardCharsets;

@Slf4j
public class ProcessUtils {

    /**
     * 运行进程(使用Args输入数据)
     *
     * @param process
     * @param opName
     * @return
     */
    public static ExecuteMessage runProcess(Process process, String opName) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            int exitValue = process.waitFor();
            executeMessage.setExitValue(exitValue);
            if (exitValue == 0) {
                //正常退出
//                log.info(opName + "成功");
                StringBuilder compileOutputStringBuilder = new StringBuilder();
                //分批获取进程的正常输出流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
                //逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    compileOutputStringBuilder.append(compileOutputLine).append("\n");
//                    log.info(compileOutputLine);
                }
                executeMessage.setMessage(compileOutputStringBuilder.toString());
            } else {//异常退出
//                log.info(opName + "失败,错误码" + exitValue);

                StringBuilder compileOutputStringBuilder = new StringBuilder();
                //分批获取进程的正常输出流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
                //逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    compileOutputStringBuilder.append(compileOutputLine).append("\n");
                }
                executeMessage.setMessage(compileOutputStringBuilder.toString());
                StringBuilder compileErrorOutputStringBuilder = new StringBuilder();
                //分批获取进程的异常输出流
                BufferedReader errorBufferReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
                //逐行读取
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = errorBufferReader.readLine()) != null) {
                    compileErrorOutputStringBuilder.append(errorCompileOutputLine);
                }
                executeMessage.setErrorMessage(compileErrorOutputStringBuilder.toString());
            }
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return executeMessage;
    }

    /**
     * 运行交互式进程(即使用Scanner实现输入数据)
     *
     * @param process
     * @param opName
     * @return
     */
    public static ExecuteMessage runInteractProcess(Process process, String opName, String args) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            OutputStream outputStream = process.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            outputStreamWriter.write(args);
            outputStreamWriter.flush();//清空缓冲区,输入到控制台中
            log.info("{}",opName + "成功");
            //分批获取进程的正常输出流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            //逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            executeMessage.setMessage(compileOutputStringBuilder.toString());
            //资源释放
            outputStream.close();
            outputStreamWriter.close();
            bufferedReader.close();
            process.destroy();

        } catch (IOException e) {
            log.error("执行错误{}", e.getMessage());
        } finally {
            // 确保进程被销毁
            if (process != null && process.isAlive()) {
                process.destroy();
            }
        }
        return executeMessage;
    }
}
